// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#ifndef __H_MK_MESH__
#define __H_MK_MESH__

#include "mk_resource.h"
#include "mk_aabb.h"
#include "mk_memory_block.h"

namespace MK3DE
{
	class CMeshDataLoader;
	class CSkeleton;

	class MK3DE_API CMesh : public CResource
	{
	public:
		typedef D3DXVECTOR3 Position;
		typedef D3DXVECTOR3 Normal;
		typedef DWORD Color;

		struct TextureCoord
		{
			TextureCoord() {}
			TextureCoord(float _tu, float _tv) : tu(_tu), tv(_tv) {}

			float tu, tv;
		};

		struct Face
		{
			DWORD vertexIndex[3];
		};

		struct Influence
		{
			BYTE boneIdx[4];
			float weight[4];
		};

		struct Header
		{
			DWORD id;
			WORD version;
			WORD dumy;
			DWORD vertexNum;
			DWORD faceNum;
			DWORD offsetPosition;
			DWORD offsetNormal;
			DWORD offsetColor;
			DWORD offsetTexCoord1;
			DWORD offsetTexCoord2;
			DWORD offsetTexCoord3;
			DWORD offsetSkin;
			DWORD offsetFace;
			BYTE reserve[16];
		};

		static const DWORD MK_MESH_ID = MAKEFOURCC('M', 'K', 'M', 'E');
		static const WORD MK_MESH_VER = MAKEWORD(1, 0);

	public:
		CMesh(const char* fileName);
		~CMesh();

		RESOURCE_TYPE GetType() { return RES_T_MESH; }

		BOOL Load();

		DWORD GetVertexCount() { return _header->vertexNum; }
		DWORD GetFaceCount() { return _header->faceNum; }

		BOOL IsSkinMesh() { return _header->offsetSkin == 0 ? FALSE : TRUE; }

		BOOL FillVertexBuffer(CSkeleton* pSkeleton, CMesh::Position* pPosition, CMesh::Normal* pNormal, DWORD vertexNum);
		BOOL FillUVBuffer(CMesh::TextureCoord* pUV, DWORD vertexNum);
		BOOL FillSkinBuffer(D3DXVECTOR4* pIndex, D3DXVECTOR4* pWeight, DWORD vertexNum);

		BOOL FillFaceBuffer(CMesh::Face* pFace, DWORD faceNum, DWORD idx_offset);

		void UpdateAABB();
		AABB GetAABB() { return _aabb; }

		BOOL CollideWithRay(D3DXMATRIX& mat, D3DXVECTOR3& pos, float x, float y, float z, D3DXVECTOR3& dir);

		DEF_SET_GET(int, MaterialIdx);

	private:
		void __Clean();

	private:
		CMemoryBlock _dataBlock;
		Header* _header;
		Position* _positions;
		Normal* _normals;
		Color* _colors;
		TextureCoord* _texCoord1;
		TextureCoord* _texCoord2;
		TextureCoord* _texCoord3;
		Influence* _skins;
		Face* _faces;

		AABB _aabb;
		int MaterialIdx;
	};
};

#endif /* __H_MK_MESH__ */